Kompozit adat típusok - ORACLE
Az egyszerű adattípusokkal szemben jóval hatékonyabban tudjuk használni a kompozit adattípusokat. Egyfelől gyorsabb az elérésük, mert a memóriában tárolódnak (pontosabban a Program Global Area-ban, de ez most nem fontos kérdés). Két fő típusa van:
Records: egy sornyi adatot tartalmaz változó értékekkel. Akkor használjuk, ha egymással összefüggő adatokat szeretnénk tárolni (mint pl. a HR sémában egy Employee adatai). Leginkább akkor látom hasznát, ha collection-nel együtt használjuk. Létrehozása két féle módon történhet:
Ha egy adatbázis tábla struktúrájára hivatkozunk:
DECLAREVagy a változókat egyenként adjuk hozzá:
r_tel phone_numbs%rowtype;
BEGIN
SELECT * INTO r_tel FROM phone_numbs WHERE id = '1';
END;
DECLARE
t_tel is record (phone_home varchar2(10), phone_mobile phone_numbs.phone_mobile%type);
r_tel t_tel;
BEGIN
SELECT phone_home, phone_mobile INTO r_tel FROM phone_numbs WHERE id = '1';
END;
Collections: több sornyi adatot tartalmaz ugyanolyan adattípussal. Ezt három féle módon tudja tárolni: mint Varray, ez esetben a benne tárolt változók index értéke 1-től nő, de meg kell határozni már létrehozásakor, hogy hány eleme lesz (ezt sok esetben nem tudjuk, ezért én nem is szoktam használni). Lehet továbbá Nested table, amelynek index értéke hasonlóan az előzőhöz 1-től nő, de nem kell meghatározni az elemszámot a létrehozásakor, azaz új érték hozzáadásakor index értéke automatikusan megnő, továbbá törölhetünk is belőle elemeket. A harmadik típus az Associative array, más néven Index by array, amelynél az index értéke bármi lehet, mi határozhatjuk meg. Ha jelentése van számunkra az Index értékének, akkor érdemes használni (pl. az index értéke lehet mondjuk 'Alma').
Nested table létrehozására példa:
DECLARE
TYPE e_tel IS TABLE OF VARCHAR2(100);
tels e_tel := e_tel();
idx pls_integer := 1;
BEGIN
FOR x IN 1..10 LOOP
tels.extend;
SELECT phone_mobile INTO tels(idx) FROM phone_numbs WHERE id = x;
idx := idx + 1;
END LOOP;
END;
Associative array létrehozására példa:
DECLARE
TYPE e_tel IS TABLE OF phone_numbs.phone_mobile%TYPE INDEX BY PLS_INTEGER;
tels e_tel;
BEGIN
FOR x IN 1..10 LOOP
SELECT phone_mobile INTO tels(idx) FROM phone_numbs WHERE id = x;
END LOOP;
END;
In Memory Table: érdemes ezt a két fő típust vegyíteni egymással, azaz collection-höz record-ot hozzáadni. Ezzel igen hatékonyan és gyorsan tudunk táblákból lekérdezéseket végezni, üzleti folyamatokat leképezni. Az alábbi példában egy táblából lekérdezzük egy tábla elemeit, azt módosítjuk, majd egy másik táblába beírjuk az új értékeket:
DECLARE
TYPE e_type IS RECORD (data_first VARCHAR2(20), data_second VARCHAR2(20));
TYPE e_list IS TABLE OF e_type INDEX BY BINARY_INTEGER;
t_list e_list;
BEGIN
sql_statement := 'SELECT a.data_first, a.data_second FROM data_table';
EXECUTE IMMEDIATE sql_statement BULK COLLECT INTO t_list;
END;
Collection esetében viszont meg kell említeni, hogy nagy méretű adatmennyiség esetén van rá esély, hogy nem fog működni, mivel a memória megtelik. Ebben az esetben érdemes lehet a cursor használata, amely nem tölti be az összes rekordot a memóriába, hanem soronként történik a memóriába írás.